#!/bin/sh

function usage()
{
    echo "A tool to be lazy"
    echo "make project according to colist"

    echo "Usage: my_make_colist [-h] clean"
    
    echo "Description:"
    echo " -h: show this usage"
    echo " clean: do not make project but clean it"
}

function defineGlobalVars
{
    DIR=`pwd`
    USER=`whoami`
    CLEAN=""
    declare -a DIRLIST
}

function getProjectDir()
{
    if [ -z $DIR ];then
        DIR=`pwd`
    fi
    if [ X`echo $DIR | grep '^/project/.\{1,\}'` == X ];then
        echo "$DIR is not a project dir" >&2
        exit 1
    fi
    local rootPath=`echo $DIR | awk -F"/" '{print $4}'`
    if [ X"$rootPath" == X ];then
        DIR=$DIR"/ccsrc"
    else
        if [ X"$rootPath" == X"ccsrc" ];then
            DIR=`echo $DIR | awk -F"/" '{printf "/%s/%s/%s", $2, $3, $4}'`
        else
            echo "rootPath of $DIR is not ccsrc" >&2
            exit 1
        fi
    fi
    local dirOwner=`ls -ld $DIR | awk '{print $3}'`
    if [ X"$dirOwner" != X"$USER" ];then
        echo "Owner of $DIR is not $USER" >&2
        exit 1
    fi
}

function checkFile()
{
    local file=$1
    if [ ! -f $file ];then
        echo "$file is not exist" >&2
        exit 1
    fi
    if [ X`ls -ld $file | awk '{print $3}'` != X"$USER" ];then
        echo "owner of $file is not $USER" >&2
        exit 1
    fi
}

function findMakefileDir()
{
    local dir=$1
    if [ $dir == $DIR ];then
        echo ""
    elif [ -f "${dir}/Makefile" ];then
        echo "$dir"
    else
        dir=`dirname $dir`
        echo `findMakefileDir $dir`
    fi
}

function isItemInDIRLIST()
{
    local item
    for item in ${DIRLIST[*]}
    do
        if [ X"$item" = X"$1" ];then
            echo yes
            break
        fi
    done
}

function makeUniqueDIRLIST()
{
    local tmpArray=()
    local item
    for item in ${DIRLIST[*]}
    do
        tmpArray[${#tmpArray[*]}]=$item
    done
    unset DIRLIST
    for item in ${tmpArray[*]}
    do
        if [ X`isItemInDIRLIST $item` = X"" ];then
            DIRLIST[${#DIRLIST[*]}]=$item
        fi
    done
}

function processColist()
{
    local colist=${DIR}/colist
    if [ ! -f $colist ];then
        echo "colist is not exist" >&2
        exit 1
    fi
    local file
    local dir
    for file in `cat $colist`
    do
        checkFile ${DIR}"/"${file}
    done
    #first push cclib dirs
    for dir in `cat $colist | grep "\.[cC]$" | sed 's/^.\///' | grep "^cclib" | xargs -I '{}' dirname '{}' | sort -u`
    do
        dir=${DIR}"/"${dir}
        dir=`findMakefileDir $dir`
        if [ X"$dir" != X ];then
            DIRLIST[${#DIRLIST[*]}]=$dir
        fi
    done
    #push other lib dirs
    local otherDirs=`cat $colist | grep "\.[cC]$" | sed 's/^.\///' | grep -v "^cclib" | xargs -I '{}' dirname '{}' | sort -u | grep -v "^\.$"`
    if [ ! -f "$DIR/Makefile.libs" ];then
        cd $DIR
        eval make Makefile.libs
    fi
    if [ ! -f "$DIR/Makefile.libs" ];then
        echo "Can not make $DIR/Makefile.libs" >&2
        exit 1
    fi
    local matchDir
    for dir in $otherDirs    
    do
        dir=${DIR}"/"${dir}
        dir=`findMakefileDir $dir`
        matchDir=${dir#${DIR}/}
        if [ `grep $matchDir ${DIR}/Makefile.libs | wc -l` -ne 0 ];then
            DIRLIST[${#DIRLIST[*]}]=$dir
            otherDirs=`echo ${otherDirs//$matchDir/}`
        fi
    done
    #push other dirs
    for dir in $otherDirs
    do
        dir=${DIR}"/"${dir}
        dir=`findMakefileDir $dir`
        if [ X"$dir" != X ];then
            DIRLIST[${#DIRLIST[*]}]=$dir
        fi
    done
    makeUniqueDIRLIST
    
}

function makeOneDir()
{
    local dir=$1
    cd $dir
    if [ $? -ne 0 ];then
        echo -e "\033[41;33m Can not enter into $dir \033[0m" >&2
        exit 1
    fi
    eval make $CLEAN
    if [ $? -ne 0 ];then
        echo -e "\033[41;33m Failed to make $dir \033[0m" >&2
        exit 1
    fi
}

function process()
{
    local dir
    for dir in ${DIRLIST[*]}
    do
        clear
        echo -e "\033[41;33m Prepare to make $dir ... \033[0m"
        sleep 1
        eval makeOneDir $dir
    done
}

for arg in "$@"
do
    case "$arg" in
        "clean") CLEAN="clean"
            ;;
        "-h") usage
            ;;
        *)  echo "Unkown argument!"
            exit 1
            ;;
    esac
done

getProjectDir
processColist
process
clear
echo "All has done!Have a good time!"
